/*! 
 * Header file for the collision detector.
 *
 * \author Devis Rossini
 * \date 20 March 2012
 */
#ifndef PHXCOLLISIONDETECTOR_H_INCLUDE_GUARD
#define PHXCOLLISIONDETECTOR_H_INCLUDE_GUARD

#include "PhxCore.h"
#include "PhxCollisionEnities.h"
#include "PhxCollisionData.h"

namespace phx
{
	/*!
     * A wrapper class that holds the collision detection routines.
     *
     * Each of the functions has the same format: it takes the details
     * of two objects, and a pointer to a contact array to fill. It
     * returns the number of contacts it wrote into the array.
     */
    class CollisionDetector
    {
    public:

		// ---------- WRAPPER FUNCTIONS ---------------------------------------------

		// Sphere - Sphere.
		static unsigned SphereAndSphere(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Sphere - Plane
		static unsigned SphereAndPlane(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Sphere - Terrain.
		static unsigned SphereAndTerrain(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Sphere - Box.
		static unsigned SphereAndBox(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Plane - Sphere.
		static unsigned PlaneAndSphere(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Plane - Plane.
		static unsigned PlaneAndPlane(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Plane - Terrain.
		static unsigned PlaneAndTerrain(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Plane - Box.
		static unsigned PlaneAndBox(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Terrain - Sphere.
		static unsigned TerrainAndSphere(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Terrain - Plane.
		static unsigned TerrainAndPlane(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Terrain - Terrain.
		static unsigned TerrainAndTerrain(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Terrain - Box.
		static unsigned TerrainAndBox(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Box - Sphere.
		static unsigned BoxAndSphere(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Box - Plane.
		static unsigned BoxAndPlane(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Box - Terrain.
		static unsigned BoxAndTerrain(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// Box - Box.
		static unsigned BoxAndBox(
			const CollisionPrimitive*	one,
			const CollisionPrimitive*	two,
			CollisionData*				data);

		// ---------- ALGORITHMS ----------------------------------------------------

		static unsigned SphereAndSphere(
			const CollisionSphere&	one,
			const CollisionSphere&	two,
			CollisionData*			data);

		static unsigned BoxAndBox(
			const CollisionBox&		one,
			const CollisionBox&		two,
			CollisionData*			data);

		static unsigned BoxAndSphere(
			const CollisionBox&		box,
			const CollisionSphere&	sphere,
			CollisionData*			data);

        static unsigned SphereAndPlane(
            const CollisionSphere&	sphere,
            const CollisionPlane&	plane,
            CollisionData*			data);

		//static unsigned SphereAndTruePlane(
		//	const CollisionSphere&	sphere,
		//	const CollisionPlane&	plane,
		//	CollisionData*			data);

		static unsigned BoxAndPlane(
			const CollisionBox&		box,
			const CollisionPlane&	plane,
			CollisionData*			data);

        static unsigned BoxAndPoint(
            const CollisionBox&		box,
            const Vector3&			point,
            CollisionData*			data);

 		static unsigned TerrainAndSphere(
 			const CollisionTerrain&	terrain,
 			const CollisionSphere&	sphere,
 			CollisionData*			data);

		// TODO: C'mon, a bit more immagination... add something!
    };
}

#endif // PHXCOLLISIONDETECTOR_H_INCLUDE_GUARD
